package main

import (
	"errors"
	"log"
)

// 链表Node 实际的hash {key,value}
type Node struct {
	key interface{} // key
	value interface{} // value
	nextNode *Node // 指向下一个节点
}

// 定义map
type maps struct {
	count uint // 个数
	length uint // 长度
	data []*Node // Node 数组
}

// 初始化map
func initMap(i int)(maps) {
	log.Println("初始化map,个数: " , i)
	// 若申请长度小于等于0，则默认给10
	if i <= 0 {
		i = 10
	}

	// 申请map
	var newMap maps
	newMap.count = 0 // 当前hash数
	newMap.length = uint(i) // 申请的map长度
	newMap.data = make([]*Node,newMap.length) // 申请的内存

	// 返回该结构体
	return newMap
}

// hash 函数
func (mp *maps)hashFunc(key interface{}) int {
	var sum int

	// 判断类型计算总和
	switch key.(type) {
	case int:
		sum = key.(int)
	case string:
		for _,v := range []byte(key.(string)) {
			sum += int(v)
		}
	}
	// 返回存储下标
	return sum % int(mp.length)
}

// 存储数据(链表)
func (mp *maps)saveData(node *Node , _id int) {
	// 空链表
	if mp.data[_id] == nil {
		mp.data[_id] = node
	} else {
		// 链表只有一个节点
		if mp.data[_id].nextNode == nil {
			mp.data[_id].nextNode = node
		} else {
			// 链表节点数超过1个
			tempNode := mp.data[_id].nextNode
			node.nextNode = tempNode
			mp.data[_id].nextNode = node
		}
	}
	// hash 个数增加1
	mp.count++
}

// 获取全部map数据
func (mp *maps)listall() ([]Node) {
	var nodes []Node

	for _,v := range mp.data {
		if nil != v {
			for v.nextNode != nil {
				nodes = append(nodes,*v)
				v = v.nextNode
			}
			nodes = append(nodes,*v)
		}
	}

	return nodes
}

func (mp *maps)get(key interface{}) (*Node) {
	// 根据hash函数获取下标ID
	_id := mp.hashFunc(key)

	currNode := mp.data[_id]
	for currNode != nil {
		if currNode.key == key {
			return currNode
		}
		currNode = currNode.nextNode
	}
	return nil
}

// 新增节点
func (mp *maps)set(key interface{} , value interface{}) {
	log.Println("set " , key , value)
	// 判断若有数据，直接修改
	node := mp.get(key)
	if nil != node {
		node.value = value
		return
	}

	// 新增
	// 根据hash函数获取下标ID
	_id := mp.hashFunc(key)

	// 申请实际的数据节点
	var newData Node

	// 为数据节点赋值
	newData.key = key
	newData.value = value
	newData.nextNode = nil

	// 插入数据
	mp.saveData(&newData,_id)
}

func (mp *maps)del(key interface{})(error) {
	log.Println("del " , key)
	// 根据hash函数获取下标ID
	_id := mp.hashFunc(key)

	currNode := mp.data[_id]
	var lastNode *Node = nil
	var foundok bool = false

	for currNode != nil {
		if currNode.key == key {
			foundok = true
			break
		}
		lastNode = currNode
		currNode = currNode.nextNode
	}
	if foundok {
		// 尾节点
		if nil == currNode {
			lastNode.nextNode = nil
		} else if nil == lastNode {
			// 头结点
			mp.data[_id] = currNode.nextNode
			currNode = nil
		} else {
			// 中间节点
			lastNode.nextNode = currNode.nextNode
			currNode = nil
		}

		mp.count--
	}
	return errors.New("not fount key")
}
